package com.jweb.framework.http;

import java.util.Map;

import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.HandlerAdapter;
import org.springframework.web.servlet.HandlerExecutionChain;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.HandlerMapping;
import org.springframework.web.servlet.ModelAndView;

import com.jweb.framework.core.channel.ChannelContext;
import com.jweb.framework.core.channel.Endpoint;
import com.jweb.framework.core.channel.URIEndpointMapping;
import com.jweb.framework.http.support.DefaultViewNameResolver;
import com.jweb.framework.http.support.Utils;
/**
 * 修改人： Thomas
 * 修改内容：新增 
 * 类说明：HTTP渠道映射
 */
public class ServletURIEndpointMapping<Request , Response> extends URIEndpointMapping<Request, Response> implements HandlerMapping, HandlerAdapter {
	
	private HandlerInterceptor[] handlerInterceptors ;
	
	private ViewNameResolver viewNameResolver = new DefaultViewNameResolver();

	/**
	 * @param handlerInterceptors the handlerInterceptors to set
	 */
	public void setHandlerInterceptors(HandlerInterceptor[] handlerInterceptors) {
		this.handlerInterceptors = handlerInterceptors;
	}

	/**
	 * @param viewNameResolver the viewNameResolver to set
	 */
	public void setViewNameResolver(ViewNameResolver viewNameResolver) {
		this.viewNameResolver = viewNameResolver;
	}

	@Override
	protected String getURIString(ChannelContext<Request, Response> channelContext) {
		return Utils.getPathInServlet((HttpServletRequest) channelContext.getRequest());
	}

	public HandlerExecutionChain getHandler(HttpServletRequest request)
			throws Exception {
		Endpoint endpoint = mapping(new ServletChannelContext(request, null));
		return new HandlerExecutionChain(endpoint , handlerInterceptors);
	}

	public long getLastModified(HttpServletRequest request, Object handler) {
		return -1L;
	}

	public ModelAndView handle(HttpServletRequest request,HttpServletResponse response, Object handler) throws Exception {
		
		Endpoint endpoint = (Endpoint) handler;
		
		ServletChannelContext servletChannelContext = new ServletChannelContext(request, response);
		Throwable throwable = null ;
		
		try {
			endpoint.service(servletChannelContext);
		} catch (Throwable t) {
			logger.error("servlet service error ", t.getMessage());
			throwable = t ;
			
		}finally{
			if(((ServletResponse) servletChannelContext.getResponse()).isCommitted()){
				return null;
			}
			if(servletChannelContext.getResponsePalyload() instanceof Map){
				return new ModelAndView(
						resolveView(request,(Map)servletChannelContext.getResponsePalyload(),servletChannelContext.getState() , throwable),
						(Map)servletChannelContext.getResponsePalyload());
			}
		}
		return null;
	}

	private String resolveView(HttpServletRequest request,Map responsePalyload, String state, Throwable t) {
		return viewNameResolver.getViewName(request, responsePalyload, state, t);
	}

	public boolean supports(Object handler) {
		return handler instanceof Endpoint;
	}
	
}
